// build : 2024052411
// The OSDP output can only output two states: high level and low level. If a relay is connected, a high level means on and a low level means off.
import { osdpClass } from './libvbar-drv-dxosdp.so'
import dxMap from './dxMap.js'
import dxCommon from './dxCommon.js'
const map = dxMap.get('default')
const osdpObj = new osdpClass();
const osdp = {}


/* -------------------------------------------------------------- */
/*                           CP Methods                           */
/* -------------------------------------------------------------- */

/**
 * OSDP Controller Initialization
 * @param {string} id Handle ID
 * @param {object} options CP-related parameters, required.
 *      @param {string} options.name The reader number in the sub-reader context attached to the current PD; this number represents the reader's ID. LibOSDP does not support this feature.
 *      @param {number} options.baud_rate Can be one of 9600/19200/38400/57600/115200/230400
 *      @param {number} options.address A 7-bit PD address. The remaining bits are ignored. The special address 0x7F is used for broadcasting. Therefore, there can be 2^7-1 devices on a multipoint channel.
 *      @param {number} options.flags This is used to modify the settings of the context. Please refer to the `OSDP_FLAG_*` macros.
 *      @param {object} options.id The static information that PD reports to CP when it receives "CMD_ID". This information must be populated by the PD application.
 * 			@param {number} options.id.version 1-byte manufacturer version number
 * 			@param {number} options.id.model 1-byte manufacturer model
 * 			@param {number} options.id.vendor_code 3-byte IEEE-allocated OUI
 * 			@param {number} options.id.serial_number PD's 4-byte serial number
 * 			@param {number} options.id.firmware_version 3-byte version (major, minor, internal version)
 *      @param {object} options.cap This is a pointer to an array of structures containing PD functionality. The array is terminated using {-1, 0, 0}. This is only used in PD operation mode.
 * 			@param {number} options.cap.function_code Capability/function code. Please refer to @ref osdp_pd_cap_function_code_e
 * 			@param {number} options.cap.compliance_level A number associated with the function code, indicating what the Product Manager (PD) can do with this function.
 * 			@param {number} options.cap.num_items Number of such capability entities in PD
 *      @param {object} options.channel The communication channel operation structure contains pointers to the send/recv functions.
 * 			@param {number} options.channel.data A pointer to the memory block that will be passed to the send/receive/flush methods. This is optional (can be set to NULL).
 * 			@param {number} options.channel.id `channel_id`; In a multipoint network, multiple PDs can share the same channel (read/write/refresh pointer). On such networks, `channel_id` is used to lock the PD to the channel. In a multipoint network, this "id" must be non-zero and unique for each bus.
 * 			@param {function} options.channel.recv A pointer to a function used to receive OSDP packets.
 * 			@param {function} options.channel.send A pointer to a function used to send OSDP packets.
 * 			@param {function} options.channel.flush A pointer to a function used to refresh the channel (optional)
 *      @param {ArrayBuffer} options.scbk A pointer to the PD's 16-byte secure channel base key. If not empty, it is used to set up the secure channel.
 */
osdp.osdpCpSetup = function (id, options) {

	// let pointer = osdpObj.osdpCpSetup()
	// if (pointer === undefined || pointer === null) {
	// 	throw new Error("nfc.init: init failed")
	// }
	// dxCommon.handleId("osdp", id, pointer)

	let pointer = dxCommon.handleId("uart", id)
	return osdpObj.osdpCpSetup(pointer, options);
}

/**
 * Release OSDP resources
 * @param {string} id Handle ID
 * @returns true/false
 */
osdp.osdpCpRefresh = function (cp_ptr) {
	return osdpObj.osdpCpRefresh(cp_ptr);
}

/**
 * You only need to apply for one OSDP application.
 * @param {string} id Handle ID
 * @param {object} cmd OSDP command structure. This is a wrapper for all individual OSDP commands.
 * 		@param {number} cmd.id 1-byte manufacturer version number
 *      @param {object} options.led LED command structure
 * 			@param {number} options.led.reader Reader number. 0 = First Reader, 1 = Second Reader, etc.
 * 			@param {number} options.led.led_number LED number. 0 = first LED, 1 = second LED, etc.
 * 			@param {object} options.led.temporary Ephemeral LED status descriptor.
 * 				Temporary Control Code:
 * 				- 0 - NOP - do not alter this LED's temporary settings.
 * 				- 1 - Cancel any temporary operation and display this LED's
 * 			    permanent state immediately.
 * 				- 2 - Set the temporary state as given and start timer immediately.
 *
 * 				Permanent Control Code:
 * 				- 0 - NOP - do not alter this LED's permanent settings.
 * 				- 1 - Set the permanent state as given.
 * 				@param {number} options.led.temporary.control_code 
 * 				@param {number} options.led.temporary.on_count The ON duration of the flash, in units of 100 ms.
 * 				@param {number} options.led.temporary.off_count The OFF duration of the flash, in units of 100 ms.
 * 				@param {number} options.led.temporary.on_color Color to set during the ON timer (see @ref osdp_led_color_e).
 * 				@param {number} options.led.temporary.off_color Color to set during the OFF timer (see @ref osdp_led_color_e).
 * 				@param {number} options.led.temporary.timer_count Time in units of 100 ms (only for temporary mode).
 * 			@param {object} options.led.permanent Permanent LED status descriptor.
 * 				Temporary Control Code:
 * 				- 0 - NOP - do not alter this LED's temporary settings.
 * 				- 1 - Cancel any temporary operation and display this LED's
 * 			    permanent state immediately.
 * 				- 2 - Set the temporary state as given and start timer immediately.
 *
 * 				Permanent Control Code:
 * 				- 0 - NOP - do not alter this LED's permanent settings.
 * 				- 1 - Set the permanent state as given.
 * 				@param {number} options.led.temporary.control_code 
 * 				@param {number} options.led.temporary.on_count The ON duration of the flash, in units of 100 ms.
 * 				@param {number} options.led.temporary.off_count The OFF duration of the flash, in units of 100 ms.
 * 				@param {number} options.led.temporary.on_color Color to set during the ON timer (see @ref osdp_led_color_e).
 * 				@param {number} options.led.temporary.off_color Color to set during the OFF timer (see @ref osdp_led_color_e).
 * 				@param {number} options.led.temporary.timer_count Time in units of 100 ms (only for temporary mode).
 * 		@param {object} options.buzzer Buzzer command structure
 * 			@param {number} options.buzzer.reader Reader number. 0 = First Reader, 1 = Second Reader, etc.
 * 			@param {number} options.buzzer.control_code 
 * 			 	Control code.
 * 				- 0 - no tone
 * 				- 1 - off
 * 				- 2 - default tone
 * 				- 3+ - TBD
 * 			@param {number} options.buzzer.on_count The ON duration of the sound, in units of 100 ms.
 * 			@param {number} options.buzzer.off_count The OFF duration of the sound, in units of 100 ms.
 * 			@param {number} options.buzzer.rep_count The number of times to repeat the ON/OFF cycle; 0: forever.
 * 		@param {object} options.text Text command structure
 * 			@param {number} options.text.reader Reader number. 0 = First Reader, 1 = Second Reader, etc.
 * 			Control code.
 *	  		- 1 - permanent text, no wrap
 *	  		- 2 - permanent text, with wrap
 *	  		- 3 - temp text, no wrap
 *	  		- 4 - temp text, with wrap
 * 			@param {number} options.text.control_code 
 * 			@param {number} options.text.temp_time Duration to display temporary text, in seconds
 * 			@param {number} options.text.offset_row Row to display the first character (1-indexed)
 * 			@param {number} options.text.offset_col Column to display the first character (1-indexed)
 * 			@param {number} options.text.length Number of characters in the string
 * 			@param {string} options.text.data The string to display
 * 		@param {object} options.output Output command structure
 * 		@param {object} options.comset Comset command structure
 * 			@param {number} options.comset.address Unit ID to which this PD will respond after the change takes effect.
 * 			@param {number} options.comset.baud_rate Baud rate. Valid values: 9600, 19200, 38400, 115200, 230400.
 * 		@param {object} options.keyset Keyset command structure
 * 			@param {number} options.keyset.type Type of keys: - 0x01 – Secure Channel Base Key
 * 			@param {number} options.keyset.length Number of bytes of key data - (Key Length in bits + 7) / 8
 * 			@param {string} options.keyset.data Key data
 * 		@param {object} options.mfg Manufacturer specific command structure
 * 			@param {number} options.mfg.vendor_code 3-byte IEEE assigned OUI. Most Significant 8-bits are unused
 * 			@param {number} options.mfg.command 1-byte manufacturer defined osdp command
 * 			@param {number} options.mfg.length length Length of command data (optional)
 * 			@param {string} options.mfg.data Command data (optional)
 * 		@param {object} options.file_tx File transfer command structure
 * 			@param {number} options.file_tx.id Pre-agreed file ID between CP and PD
 * 			@param {number} options.file_tx.flags Reserved and set to zero by OSDP spec.
 * 				@note: The upper bits are used by libosdp as:
 *    				bit-31 - OSDP_CMD_FILE_TX_FLAG_CANCEL: cancel an ongoing transfer
 * 		@param {object} options.status Status report command structure
 * 			@param {object} options.status.type The kind of event to report see `enum osdp_event_status_type_e`
 * 				OSDP_STATUS_REPORT_INPUT 	0 Status report of the inputs attached the PD
 * 				OSDP_STATUS_REPORT_OUTPUT 	1 Status report of the output attached the PD
 * 				OSDP_STATUS_REPORT_LOCAL	2 Local tamper and power status report Bit-0: tamper Bit-1: power
 * 				OSDP_STATUS_REPORT_REMOTE	3 Remote tamper and power status report Bit-0: tamper Bit-1: power
 * 			@param {number} options.status.nr_entries Number of valid bits in `status`
 * 			@param {number} options.status.mask Status bit mask
 * @returns true/false
 */
osdp.osdpCpSendCommand = function (cp_ptr, command) {
	return osdpObj.osdpCpSendCommand(cp_ptr, command);
}

/**
 * Set event callback function
 * @param {number} osdp identifier; different devices have different identifiers; this field is required.
 * @returns true/false
 */
osdp.osdpCpSetEventCallback = function (cp_ptr, func) {
	return osdpObj.osdpCpSetEventCallback(cp_ptr, func);
}

/**
 * Clear command queue
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @returns true/false
 */
osdp.osdpCpTeardown = function (cp_ptr) {
	return osdpObj.osdpCpTeardown(cp_ptr);
}

/**
 * Refresh command queue
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @returns true/false
 */
osdp.osdpCpFlushCommands = function (cp_ptr) {
	return osdpObj.osdpCpFlushCommands(cp_ptr);
}

/**
 * Get PD ID information
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} pd_num Device address
 * @returns true/false
 */
osdp.osdpCpGetPdId = function (cp_ptr, pd_num) {
	return osdpObj.osdpCpGetPdId(cp_ptr, pd_num);
}

/**
 * Release specified OSDP
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} pd_num Device address
 * @param {number} function_code function number
 * 		For detailed function parameters, please refer to the `osdp_pd_cap_function_code_e` structure in `osdp.h`.
 * @returns true/false
 */
osdp.osdpCpGetCapability = function (cp_ptr, pd_num, function_code) {
	return osdpObj.osdpCpGetCapability(cp_ptr, pd_num, function_code);
}

/**
 * Modify PD's flag
 * @param {number} cp_ptr Device pointer
 * @param {number} pd ，Different devices have different labels; this field is required.
 * @param {number} flags Device mode: OSDP_FLAG_ENFORCE_SECURE 0x00010000 0; Recommended for use in production environments. OSDP_FLAG_INSTALL_MODE 0x00020000 1; OSDP_FLAG_IGN_UNSOLICITED 0x00040000 2;

#define 
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @returns true/false
 */
osdp.osdpCpModifyFlag = function (cp_ptr, pd, flags, do_set) {
	return osdpObj.osdpCpModifyFlag(cp_ptr, pd, flags, do_set);
}

/* -------------------------------------------------------------- */
/*                           PD Methods                           */
/* -------------------------------------------------------------- */

/**
 * Specify OSDP output high/low level
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} value Only 1 and 0 are allowed. 1 represents a high level and 0 represents a low level. The default is a high level. This field is required.
 * @returns true/false
 */
osdp.osdpPdSetup = function (id, options) {
	let pointer = dxCommon.handleId("uart", id)
	return osdpObj.osdpPdSetup(pointer, options);
}

/**
 * Get the current output of the specified OSDP: high/low level
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @returns 1 and 0, where 1 represents a high level and 0 represents a low level.
 */
osdp.osdpPdRefresh = function (pd_ptr) {
	return osdpObj.osdpPdRefresh(pd_ptr);
}

/**
 * Set callback function
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} state Pull-up view, required field
 * @returns true/false
 */
osdp.osdpPdSetCommandCallback = function (pd_ptr, func) {
	return osdpObj.osdpPdSetCommandCallback(pd_ptr, func);
}

/**
 * Send to CP event
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} state Pull-up view, required field
 * @returns true/false
 */
osdp.osdpPdNotifyEvent = function (pd_ptr, event) {
	return osdpObj.osdpPdNotifyEvent(pd_ptr, event);
}

/**
 * Clear all events
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} state Pull-up view, required field
 * @returns true/false
 */
osdp.osdpPdTeardown = function (pd_ptr) {
	return osdpObj.osdpPdTeardown(pd_ptr);
}

/**
 * Refresh Event
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} state Pull-up view, required field
 * @returns true/false
 */
osdp.osdpPdFlushEvents = function (pd_ptr, event) {
	return osdpObj.osdpPdFlushEvents(pd_ptr, event);
}

/**
 * Settings
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {object array} capConfigArray Device Capability Function Array List
 * 		For detailed function parameters, please refer to the `osdp_pd_cap_function_code_e` structure in `osdp.h`.
 * 		capConfigArray[0].function_code 	Functional type
 *      capConfigArray[0].compliance_level 	Functional hierarchy
 *      capConfigArray[0].num_items 		Number of features
 * 		......
 * @returns true/false
 */
osdp.osdpPdSetCapabilities = function (pd_ptr, capConfigArray) {
	return osdpObj.osdpPdSetCapabilities(pd_ptr, capConfigArray);
}

/* -------------------------------------------------------------- */
/*                         Common Methods                         */
/* -------------------------------------------------------------- */
/**
 * Initialization log
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} state Pull-up view, required field
 * @returns true/false
 */
osdp.osdpLoggerInit = function (pd_ptr) {
	return osdpObj.osdpLoggerInit(pd_ptr);
}

/**
 * Set log callback
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} state Pull-up view, required field
 * @returns true/false
 */
osdp.osdpSetLogCallback = function (pd_ptr) {
	return osdpObj.osdpSetLogCallback(pd_ptr);
}

/**
 * Get version number
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} state Pull-up view, required field
 * @returns true/false
 */
osdp.osdpGetVersion = function (pd_ptr) {
	return osdpObj.osdpGetVersion(pd_ptr);
}

/**
 * Obtaining information
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} state Pull-up view, required field
 * @returns true/false
 */
osdp.osdpGetSourceInfo = function (pd_ptr) {
	return osdpObj.osdpGetSourceInfo(pd_ptr);
}

/**
 * Get mask
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} state Pull-up view, required field
 * @returns true/false
 */
osdp.osdpGetStatusMask = function (pd_ptr) {
	return osdpObj.osdpGetStatusMask(pd_ptr);
}

/**
 * Get sc mask
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} state Pull-up view, required field
 * @returns true/false
 */
osdp.osdpGetScStatusMask = function (pd_ptr) {
	return osdpObj.osdpGetScStatusMask(pd_ptr);
}

/**
 * Registration file operation method
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} state Pull-up view, required field
 * @returns true/false
 */
osdp.osdpFileRegisterOps = function (pd_ptr) {
	return osdpObj.osdpFileRegisterOps(pd_ptr);
}

/**
 * Get file transfer status
 * @param {number} osdp The identifier varies depending on the device; this field is required.
 * @param {number} state Pull-up view, required field
 * @returns true/false
 */
osdp.osdpGetFileTxStatus = function (pd_ptr) {
	return osdpObj.osdpGetFileTxStatus(pd_ptr);
}


/**
 * Check if the OSDP message queue is empty.
 * @returns true/false
 */
osdp.msgIsEmpty = function () {
	return osdpObj.msgIsEmpty()
}

/**
 * Read data from the OSDP message queue.
 * @returns json
 */
osdp.msgReceive = function () {
	return JSON.parse(osdpObj.msgReceive());
}

/**
 * Get OSDP queue size
 * @returns num
 */
osdp.msgSize = function () {
	return osdpObj.msgSize();
}

export default osdp;
